#include "fft.h"
#include"setgpio.h"
#include"touchscr.h"
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define pixyzero 260
#define pixxzero 355
#define xstartscr 60
#define xendscr 720
#define ystartscr 40

struct rect
{
    int x;
    int y;
    int xend;
    int yend;
};

struct BITMAPFILEHEADER
{
    short bfType;
    long bfSize;
    short bfReserved1;
    short bfReserved2;
    long bfOffBits;
};

struct BITMAPINFOHEADER
{
    long biSize;
    long biWidth;
    long biHeight;
    short biPlanes;
    short biBitCount;
    long biCompression;
    long biSizeImage;
    long biXPelsPerMeter;
    long biYPelsPerMeter;
    long biClrUsed;
    long biClrImportant;
};

union readbmpfileheader {
    char r[14];
    struct BITMAPFILEHEADER fh;
};

union readbmpinfoheader {
    char r[40];
    struct BITMAPINFOHEADER ih;
};

struct bitmapmem
{
    short *col;
    int x;
    int y;
};

struct button
{
    char type;
    char trsp;
    struct bitmapmem pressed;
    struct rect position;
    void (*func)();
};

unsigned short scalecheck[] = {10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000};

struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
short *backbuffer;
short *pfb;
struct bitmapmem background, num0, num1, num2, num3, num4, num5, num6, num7, num8, num9, nump, numf,nume, ch1measure, ch2measure, ch1seloff, ch2seloff, hpressleft, hpressright, pressout, presscount, start, startpress, stoppress, trigeron, trigpressbott, trigpresstop, vpressbott, vpresstop;
struct button ch1s, ch2s, countb, outb, startb, stopb, hbl, hbr, vbt, vbb;
float rdsen[13];
char readstr[5];
short channela[131072];
short channelb[131072];
struct complex channelafft[131072];
struct complex channelbfft[131072];
char ch1on = 1;
char ch2on = 1;
char count1on = 0;
char count2on = 0;
short ay = 500; //x单位为点个数，y单位为毫伏
short by = -500;
short ax = 0;
short bx = 0;
char axsc = 5;
char aysc = 5;
char bxsc = 5;
char bysc = 5;
short triga = 1000;
short trigb = 0;
char trigchn = 1;
char running = 1;
char fftortime = 0;
short touchx, touchy;
char touched=0;
struct button *touchb=NULL;
float smfreq = 100;//MSPS

void present(int fp);
void setbackbuffer();
void strechrect(struct rect rects, struct rect rectd, short *src, int flag);
short r8g8b8tor5g6b5(unsigned char r, unsigned char g, unsigned char b);
struct bitmapmem readbmp(char *addr);
void getbmp();
void switchnum(struct rect rects, struct rect rectd, int num);
void printnum(int x, int y, float num);
void getbutton();
void rendbutton();
void dobuttonact(char);
void rendtime();
void countfft();
void rendfft();

void ch1sfunc();
void ch2sfunc();
void ffton();
void setout();
void setstart();
void setstop();
void hblfunc();
void hbrfunc();
void vbtfunc();
void vbbfunc();

int main()
{
    startmmap();
    setiic();
    setupscr();
    int fp = 0;
    int fdata = 0;
    fp = open("/dev/fb0", O_RDWR);
    fdata = open("data.txt", O_RDONLY);
    if (fp < 0)
    {
        printf("Error : Can not open framebuffer device/n");
        exit(1);
    }

    if (ioctl(fp, FBIOGET_FSCREENINFO, &finfo))
    {
        printf("Error reading fixed information/n");
        exit(2);
    }

    if (ioctl(fp, FBIOGET_VSCREENINFO, &vinfo))
    {
        printf("Error reading variable information/n");
        exit(3);
    }

    pfb = mmap(NULL, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fp, 0);
    setbackbuffer();
    close(fp);
    printf("The mem is :%d\n", finfo.smem_len);
    printf("The line_length is :%d\n", finfo.line_length);
    printf("The xres is :%d\nThe vxres is:%d\n", vinfo.xres, vinfo.xres_virtual);
    printf("The yres is :%d\nThe vyres is:%d\n", vinfo.yres, vinfo.yres_virtual);
    printf("The offset of x and y is:%d,%d\n", vinfo.xoffset, vinfo.yoffset);
    printf("bits_per_pixel is :%d\n", vinfo.bits_per_pixel);
    getbmp();
    getbutton();
    printf("getall!\n");
    struct rect rec0 = {0, 0, 799, 479};
    //struct rect rec1={0,0,105,220};
    countspinfac();
    setnum(channela, channelb);
    printf("start\n");
    do
    {
        strechrect((struct rect){0, 0, 800, 480}, rec0, background.col, 0);
        if (touched)
        {
            if((measurez2()-measurez1())<100){
                touched = 1;
                touchx = measurex();
                touchy = measurey();
                dobuttonact(0);
            }
            else{
                touched = 0;
                //执行按钮任务
                dobuttonact(1);
            }
        }
        else{
            if ((measurez2() - measurez1()) < 100)
            {
                touched = 1;
                touchx = measurex();
                touchy = measurey();
            }
        }
        if (running)
        {
            //获取数据并转换
        }
        else
        {
            strechrect((struct rect){0, 0, start.x, start.y}, (struct rect){0, 0, 0, 0}, start.col, 1);
        }
        rendtime();
        printnum(68, 8, ((float)(scalecheck[axsc]) / (smfreq * 1000.0)));
        printnum(316, 8, (float)(scalecheck[aysc]));
        present(backbuffer);

    } while (1);
    munmap(pfb, finfo.smem_len);
    gpioummap();
}

void present(int fp)
{
    memcpy(pfb, backbuffer, 768000);
}

void setbackbuffer()
{
    backbuffer = (short *)malloc(768000);
}

void strechrect(struct rect rects, struct rect rectd, short *src, int flag)
{ //0复制，1过滤白色，2叠加，3过滤黑色
    if (rectd.x < 0 || rectd.x > 799 || rectd.y < 0 || rectd.y > 479 || rectd.xend <= 0 || rectd.xend > 799 || rectd.yend <= 0 || rectd.yend > 479 || rectd.x >= rectd.xend || rectd.y >= rectd.yend)
    {
        return;
    }
    else
    {
        if (flag == 0)
        {
            int i = 0;
            short *start;
            do
            {
                start = backbuffer + (rectd.y + i) * 800 + rectd.x;
                if ((rects.xend + rectd.x) <= 800)
                {
                    memcpy(start, src + i * rects.xend, 2 * rects.xend);
                }
                else
                {
                    memcpy(start, src + i * rects.xend, 2 * (800 - rectd.x));
                }
                i = i + 1;
            } while (i < rects.yend);
        }
        else if (flag == 1)
        {
            int x, y;
            x = 0;
            y = 0;
            do
            {
                if (src[x + (rects.xend) * y] >= 0xffff)
                {
                    x = x + 1;
                }
                else
                {
                    backbuffer[rectd.x + x + (rectd.y + y) * 800] = src[x + (rects.xend) * y];
                    x = x + 1;
                }
                if (x >= (rects.xend-1))
                {
                    y = y + 1, x = 0;
                }
            } while (y < rects.yend);
        }
        else if (flag == 2)
        {
            int x, y;
            x = 0;
            y = 0;
            do
            {
                if (src[x + (rects.xend) * y] == 0)
                {
                    x = x + 1;
                }
                else
                {
                    int new = 0;
                    new = (backbuffer[rectd.x + x + (rectd.y + y) * 800] & 0x1f) + (src[x + (rects.xend) * y] + 0x1f);
                    if (new > 0x1f)
                    {
                        new = 0x1f;
                    }
                    new += (backbuffer[rectd.x + x + (rectd.y + y) * 800] & 0x7e0) + (src[x + (rects.xend) * y] + 0x7e0);
                    if (new > 0x7ff)
                    {
                        new = new | 0x7e0;
                    }
                    new += (backbuffer[rectd.x + x + (rectd.y + y) * 800] & 0xf800) + (src[x + (rects.xend) * y] + 0xf800);
                    if (new > 0xf800)
                    {
                        new = new | 0xf800;
                    }
                    backbuffer[rectd.x + x + (rectd.y + y) * 800] = new;
                    x = x + 1;
                }
                if (x == rects.xend)
                {
                    y = y + 1, x = 0;
                }
            } while (y < rects.yend);
        }
        else
        {
            int x, y;
            x = 0;
            y = 0;
            do
            {
                if (src[x + (rects.xend) * y] == 0)
                {
                    x = x + 1;
                }
                else
                {
                    backbuffer[rectd.x + x + (rectd.y + y) * 800] = src[x + (rects.xend) * y];
                    x = x + 1;
                }
                if (x >= (rects.xend-1))
                {
                    y = y + 1, x = 0;
                }
            } while (y < rects.yend);
        }
    }
}

short r8g8b8tor5g6b5(unsigned char r, unsigned char g, unsigned char b)
{
    return (((unsigned short)r << 8) & 0xf800) + (((unsigned short)g << 3) & 0x07e0) + (((unsigned short)b >> 3) & 0x001f);
}

struct bitmapmem readbmp(char *addr)
{
    int bmpf;
    union readbmpfileheader rfh;
    union readbmpinfoheader rih;
    struct bitmapmem bitmap;
    bmpf = open(addr, O_RDONLY);
    read(bmpf, rfh.r, 14);
    read(bmpf, rih.r, 40);
    bitmap.x = rih.ih.biWidth;
    bitmap.y = rih.ih.biHeight;
    int line = rih.ih.biSizeImage / bitmap.y;
    int length = rih.ih.biWidth * rih.ih.biHeight;
    int i = 0, j = 0;
    unsigned char bgr[3];
    bitmap.col = (short *)malloc(length * 2);
    short *tem = (short *)malloc(length * 2);
    do
    {
        read(bmpf, bgr, 3);
        i = i + 3;
        tem[j] = r8g8b8tor5g6b5(bgr[2], bgr[1], bgr[0]);
        j = j + 1;
        if (i >= bitmap.x * 3)
        {
            if (i == line)
            {
                i = 0;
            }
            else
            {
                read(bmpf, bgr, line - i);
                i = 0;
            }
        }
    } while (j < length);
    close(bmpf);
    i = 0;
    j = rih.ih.biHeight - 1;
    do
    {
        memcpy(bitmap.col + i * rih.ih.biWidth, tem + j * rih.ih.biWidth, rih.ih.biWidth * 2);
        i = i + 1;
        j = j - 1;
    } while (j >= 0);
    free(tem);
    return bitmap;
}

void getbmp()
{

    //struct bitmapmem readbmp(char * addr);
    background = readbmp("background1.bmp");
    ch1measure = readbmp("ch1measure.bmp");
    ch2measure = readbmp("ch2measure.bmp");
    ch1seloff = readbmp("ch1seloff.bmp");
    ch2seloff = readbmp("ch2seloff.bmp");
    hpressleft = readbmp("hpressleft.bmp");
    hpressright = readbmp("hpressright.bmp");
    pressout = readbmp("presout.bmp");
    presscount = readbmp("presscount.bmp");
    start = readbmp("start.bmp");
    startpress = readbmp("startpress.bmp");
    stoppress = readbmp("stoppress.bmp");
    trigeron = readbmp("trigeron.bmp");
    trigpressbott = readbmp("trigpressbott.bmp");
    trigpresstop = readbmp("trigpresstop.bmp");
    vpressbott = readbmp("vpressbott.bmp");
    vpresstop = readbmp("vpresstop.bmp");
    num0 = readbmp("0.bmp");
    num1 = readbmp("1.bmp");
    num2 = readbmp("2.bmp");
    num3 = readbmp("3.bmp");
    num4 = readbmp("4.bmp");
    num5 = readbmp("5.bmp");
    num6 = readbmp("6.bmp");
    num7 = readbmp("7.bmp");
    num8 = readbmp("8.bmp");
    num9 = readbmp("9.bmp");
    nume = readbmp("e.bmp");
    nump = readbmp("point.bmp");
    numf = readbmp("minus.bmp");
}

void printnum(int x, int y, float num)
{
    struct rect rec2 = {0, 0, 18, 24};
    struct rect rec0 = {x, y, 799, 479};
    if (num < 0)
    {
        strechrect(rec2, rec0, numf.col, 1);
        num = -num;
        rec0.x = rec0.x + 12;
    }
    if (num < 0.001)
    {
        strechrect(rec2, rec0, num0.col, 1);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, nump.col, 1);
        rec0.x = rec0.x + 6;
        strechrect(rec2, rec0, num0.col, 1);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, num0.col, 1);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, num0.col, 1);
        rec0.x = rec0.x + 14;
        int a = num * 10000 + 0.5;
        switchnum(rec2, rec0, a);
    }
    else if (num < 10.0)
    {
        int a;
        float t;
        a = (int)num;
        switchnum(rec2, rec0, a);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, nump.col, 1);
        t = num - (float)a;
        a = (t *10.0);
        rec0.x = rec0.x + 6;
        switchnum(rec2, rec0, a);
        t = t - a * 0.1;
        a = t *100.0;
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, a);
        t = t - a * 0.01;
        a = t * 1000.0 + 0.5;
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, a);
    }
    else if (num < 100.0)
    {
        int a;
        float t;
        a = (int)num;
        a = a / 10;
        switchnum(rec2, rec0, a);
        rec0.x = rec0.x + 14;
        a = ((int)num) % 10;
        switchnum(rec2, rec0, a);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, nump.col, 1);
        a = (int)num;
        t = num - (float)a;
        a = (t / 0.1);
        rec0.x = rec0.x + 6;
        switchnum(rec2, rec0, a);
        t = num * 10;
        a = (int)t;
        a = (int)((t - (float)a) * 10.0 + 0.5);
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, a);
    }
    else if(num<1000.0)
    {
        int a = num / 100;
        switchnum(rec2, rec0, a);
        a = num / 10;
        a = a % 10;
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, a);
        a = (int)num;
        a = a % 10;
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, a);
        rec0.x = rec0.x + 14;
        strechrect(rec2, rec0, nump.col, 1);
        a = (num * 10.0 + 0.5);
        a = a % 10;
        rec0.x = rec0.x + 6;
        switchnum(rec2, rec0, a);
    }
    else{
        int t = log10f(num);
        printnum(x, y, num / pow(10, t));
        rec0.x = rec0.x + 62;
        strechrect(rec2, rec0, nume.col, 1);
        rec0.x = rec0.x + 14;
        switchnum(rec2, rec0, t);
    }
}

void switchnum(struct rect rects, struct rect rectd, int num)
{
    switch (num)
    {
    case 0:
        strechrect(rects, rectd, num0.col, 1);
        break;
    case 1:
        strechrect(rects, rectd, num1.col, 1);
        break;
    case 2:
        strechrect(rects, rectd, num2.col, 1);
        break;
    case 3:
        strechrect(rects, rectd, num3.col, 1);
        break;
    case 4:
        strechrect(rects, rectd, num4.col, 1);
        break;
    case 5:
        strechrect(rects, rectd, num5.col, 1);
        break;
    case 6:
        strechrect(rects, rectd, num6.col, 1);
        break;
    case 7:
        strechrect(rects, rectd, num7.col, 1);
        break;
    case 8:
        strechrect(rects, rectd, num8.col, 1);
        break;
    case 9:
        strechrect(rects, rectd, num9.col, 1);
        break;
    default:
        strechrect(rects, rectd, num0.col, 1);
        break;
    }
}

void rendbutton()
{
    if ((*touchb).type == 0)
    {
        return;
    }
    else
    {
        strechrect((struct rect){0, 0, (*touchb).pressed.x, (*touchb).pressed.y}, (*touchb).position, (*touchb).pressed.col, (*touchb).trsp);
    }
    return;
}

void getbutton()
{
    //struct button ch1s, ch2s, countb, outb, startb, stopb, hbl, hbr, vbt, vbb;
    ch1s.position = (struct rect){0, 39, 59, 149};
    ch1s.pressed = ch1seloff;
    ch1s.trsp = 1;
    ch1s.type = 0;
    ch1s.func = ch1sfunc;
    ch2s.position = (struct rect){0, 150, 59, 260};
    ch2s.pressed = ch2seloff;
    ch2s.trsp = 1;
    ch2s.type = 0;
    ch2s.func = ch2sfunc;
    countb.position = (struct rect){0, 261, 59, 371};
    countb.pressed = presscount;
    countb.trsp = 1;
    countb.type = 0;
    countb.func = ffton;
    outb.position = (struct rect){0, 372, 59, 479};
    outb.pressed = pressout;
    outb.trsp = 1;
    outb.type = 0;
    outb.func = setout;
    startb.position = (struct rect){723, 0, 799, 39};
    startb.pressed = startpress;
    startb.trsp = 1;
    startb.type = 0;
    startb.func = setstart;
    stopb.position = (struct rect){723, 0, 799, 39};
    stopb.pressed = stoppress;
    stopb.trsp = 1;
    stopb.type = 0;
    stopb.func = setstop;
    hbl.position = (struct rect){513, 0, 722, 39};
    hbl.pressed = hpressleft;
    hbl.trsp = 1;
    hbl.type = 0;
    hbl.func = hblfunc;
    hbr.position = (struct rect){513, 0, 722, 39};
    hbr.pressed = hpressright;
    hbr.trsp = 1;
    hbr.type = 0;
    hbr.func = hbrfunc;
    hbr.func = hbrfunc;
    vbt.position = (struct rect){723, 40, 799, 260};
    vbt.pressed = vpresstop;
    vbt.trsp = 1;
    vbt.type = 0;
    vbt.func = vbtfunc;
    vbb.position = (struct rect){723, 40, 799, 260};
    vbb.pressed = vpressbott;
    vbb.trsp = 1;
    vbb.type = 0;
    vbb.func = vbbfunc;
}

void ch1sfunc()
{
    if (ch1s.type == 1)
    {
        if (ch1on == 0)
        {
            ch1on = 1;
        }
        else
        {
            ch1on = 0;
        }
    }
    else
    {
        if (count1on == 0)
        {
            count1on = 1;
        }
        else
        {
            count1on = 0;
        }
    }
    ch1s.type = 0;
}

void ch2sfunc()
{
    if (ch2s.type == 1)
    {
        if (ch2on == 0)
        {
            ch2on = 1;
        }
        else
        {
            ch2on = 0;
        }
    }
    else
    {
        if (count2on == 0)
        {
            count2on = 1;
        }
        else
        {
            count2on = 0;
        }
    }
    ch2s.type = 0;
}

void ffton()
{
    if (fftortime == 0)
    {
        fftortime = 1;
    }
    else
    {
        fftortime = 0;
    }
    countb.type = 0;
}

void setout()
{
    outb.type = 0;
    return;
}

void setstart()
{
    running = 1;
    startb.type = 0;
}

void setstop()
{
    running = 0;
    stopb.type = 0;
}

void hblfunc()
{
    if (hbl.type == 1)
    {
        ax = ax + 10;
        bx = bx + 10;
    }
    else
    {
        axsc = axsc + 1;
        if (axsc > 11)
        {
            axsc = 11;
        }
        bxsc = bxsc + 1;
        if (bxsc > 11)
        {
            bxsc = 11;
        }
    }
    hbl.type = 0;
}

void hbrfunc()
{
    if (hbr.type == 1)
    {
        ax = ax - 10;
        bx = bx - 10;
    }
    else
    {
        axsc = axsc - 1;
        if (axsc < 0)
        {
            axsc = 0;
        }
        bxsc = bxsc - 1;
        if (bxsc < 0)
        {
            bxsc = 0;
        }
    }
    hbr.type = 0;
}

void vbtfunc()
{
    if (vbt.type == 1)
    {
        ay = ay + ch1on * aysc / 5;
        by = by + ch2on * bysc / 5;
    }
    else
    {
        aysc = aysc - ch1on;
        if (aysc < 0)
        {
            aysc = 0;
        }
        bysc = bysc - ch2on;
        if (bysc < 0)
        {
            bysc = 0;
        }
    }
    vbt.type = 0;
}

void vbbfunc()
{
    if (vbb.type == 1)
    {
        ay = ay - ch1on * aysc / 5;
        by = by - ch2on * bysc / 5;
    }
    else
    {
        aysc = aysc + ch1on;
        if (aysc > 11)
        {
            aysc = 11;
        }
        bysc = bysc + ch2on;
        if (bysc > 11)
        {
            bysc = 11;
        }
    }
    vbb.type = 0;
}

void rendtime()
{
    int i = 0;
    int midtime = 65536;
    int low, high;
    if (trigchn == 1)
    {
        int trignum = 0;
        int trigtime[15];
        i = 1;
        do
        {
            if ((channela[i] & 0x8000) && (~(channela[i - 1] & 0x8000)))
            {
                if (trignum < 15)
                {
                    trigtime[trignum] = i;
                }
                trignum = trignum + 1;
            }
            i = i + 1;
        } while (i < 131072);
        if (trignum >= 2)
        {
            if (trignum < 15)
            {
                midtime = trigtime[trignum / 2];
            }
            else
            {
                if (trigtime[14] >= 65536)
                {
                    i = 14;
                    do
                    {
                        if (trigtime[i] <= 65536)
                        {
                            midtime = trigtime[i];
                            break;
                        }
                        i = i - 1;
                    } while (i > 0);
                }
                else
                {
                    i = 65536;
                    int j = 0;
                    do
                    {
                        if ((channela[i - j] & 0x8000) && (~(channela[i - j - 1] & 0x8000)))
                        {
                            midtime = i - j;
                            break;
                        }
                        if ((channela[i + j] & 0x8000) && (~(channela[i + j - 1] & 0x8000)))
                        {
                            midtime = i + j;
                            break;
                        }
                        j = j + 1;
                    } while (j < 65535);
                }
            }
        }
        else if (trignum == 1)
        {
            midtime = trigtime[trignum];
        }
        midtime = midtime + ax;
        low = midtime - scalecheck[axsc] * 4;
        high = midtime + scalecheck[axsc] * 5;
    }
    else if (trigchn == 2)
    {
        int trignum = 0;
        int trigtime[15];
        i = 1;
        do
        {
            if ((channelb[i] & 0x8000) && (~(channelb[i - 1] & 0x8000)))
            {
                if (trignum < 15)
                {
                    trigtime[trignum] = i;
                }
                trignum = trignum + 1;
            }
            i = i + 1;
        } while (i < 131072);
        if (trignum >= 2)
        {
            if (trignum < 15)
            {
                midtime = trigtime[trignum / 2];
            }
            else
            {
                if (trigtime[14] >= 65536)
                {
                    i = 14;
                    do
                    {
                        if (trigtime[i] <= 65536)
                        {
                            midtime = trigtime[i];
                            break;
                        }
                        i = i - 1;
                    } while (i > 0);
                }
                else
                {
                    i = 65536;
                    int j = 0;
                    do
                    {
                        if ((channelb[i - j] & 0x8000) && (~(channelb[i - j - 1] & 0x8000)))
                        {
                            midtime = i - j;
                            break;
                        }
                        if ((channelb[i + j] & 0x8000) && (~(channelb[i + j - 1] & 0x8000)))
                        {
                            midtime = i + j;
                            break;
                        }
                        j = j + 1;
                    } while (j < 65535);
                }
            }
        }
        else if (trignum == 1)
        {
            midtime = trigtime[trignum];
        }
        midtime = midtime + ax;
        low = midtime - scalecheck[axsc] * 4;
        high = midtime + scalecheck[axsc] * 5;
    }
    i = 0;
    float xscraddpix = (float)(xendscr - xstartscr) / (float)(high - low - 1);
    short pixy = 0;
    short pixx = 0;
    float sya = (float)scalecheck[aysc] / 73.3;
    float syb = (float)scalecheck[bysc] / 73.3;
    if(low<0){
        low = 0;
    }
    if(high>=131072){
        high = 131071;
    }
    do
    {
        pixx = xstartscr + (i * xscraddpix);
        if(ch1on){
        pixy = -((float)(channela[low + i] + (float)ay) / sya) + (float)pixyzero;
        if (ystartscr < pixy && pixy < 479)
        {
            backbuffer[pixx + pixy * 800] = 0x001f;
            backbuffer[pixx + (pixy - 1) * 800] = 0x001f;
            backbuffer[pixx + 1 + (pixy - 1) * 800] = 0x001f;
            backbuffer[pixx + 1 + pixy * 800] = 0x001f;
        }
        }
        //pixx = xstartscr + (i * xscraddpix);
        if(ch2on){
        pixy = -((float)(channelb[low + i] + (float)by) / syb) + (float)pixyzero;
        if (ystartscr < pixy && pixy < 479)
        {
            backbuffer[pixx + pixy * 800] = 0xffe0;
            backbuffer[pixx + (pixy - 1) * 800] = 0xffe0;
            backbuffer[pixx + 1 + (pixy - 1) * 800] = 0xffe0;
            backbuffer[pixx + 1 + pixy * 800] = 0xffe0;
        }
        }
        i = i + 1;
    } while ((low + i) < high);
}

void countfft()
{
    int i = 0;
    do
    {
        channelafft[i] = (struct complex){channela[i], 0};
        channelbfft[i] = (struct complex){channelb[i], 0};
        i = i + 1;
    } while (i < 131072);
    if (ch1on)
    {
        fft131072(channelafft, 131072);
    }
    if (ch2on)
    {
        fft131072(channelbfft, 131072);
    }
    changeorder(channelafft, channelbfft);
}

void rendfft()
{
    if (ch1on && (~ch2on))
    {
        int i = 0;
        int pixx = xstartscr;
        int pixy = 0;
        float sya = (float)scalecheck[aysc] / 73.3;
        do
        {
            pixy = -(float)((sqrtf((channelafft[i].re * channelafft[i].re) + (channelafft[i].im * channelafft[i].im)) + ay) / sya) + pixyzero;
            pixx = (float)((float)((float)i / 65536.0) * 660.0) + xstartscr;
            if (ystartscr < pixy && pixy < 479)
            {
                backbuffer[pixx + pixy * 800] = 0x001f;
            }
            i = i + 1;
        } while (i < 65536);
    }
    else if ((~ch1on) && (ch2on))
    {
        int i = 0;
        int pixx = xstartscr;
        int pixy = 0;
        float syb = (float)scalecheck[bysc] / 73.3;
        do
        {
            pixy = -(float)((sqrtf((channelbfft[i].re * channelbfft[i].re) + (channelbfft[i].im * channelbfft[i].im)) + by) / syb) + pixyzero;
            pixx = (float)((float)((float)i / 65536.0) * 660.0) + xstartscr;
            if (ystartscr < pixy && pixy < 479)
            {
                backbuffer[pixx + pixy * 800] = 0xffe0;
            }
            i = i + 1;
        } while (i < 65536);
    }
    else
    {
        int i = 0;
        int pixx = xstartscr;
        int pixy = 0;
        float syb = (float)scalecheck[bysc] / 73.3;
        float sya = (float)scalecheck[aysc] / 73.3;
        do
        {
            pixy = -(float)((sqrtf((channelafft[i].re * channelafft[i].re) + (channelafft[i].im * channelafft[i].im)) + ay) / sya) + pixyzero;
            pixx = (float)((float)((float)i / 65536.0) * 660.0) + xstartscr;
            if (ystartscr < pixy && pixy < 479)
            {
                backbuffer[pixx + pixy * 800] = 0x001f;
            }
            pixy = -(float)((sqrtf((channelbfft[i].re * channelbfft[i].re) + (channelbfft[i].im * channelbfft[i].im)) + by) / syb) + pixyzero;
            pixx = (float)((float)((float)i / 65536.0) * 660.0) + xstartscr;
            if (ystartscr < pixy && pixy < 479)
            {
                backbuffer[pixx + pixy * 800] = 0xffe0;
            }
            i = i + 1;
        } while (i < 65536);
    }
}

void dobuttonact(char fs){
    //struct button ch1s, ch2s, countb, outb, startb, stopb, hbl, hbr, vbt, vbb;
    if(touchb!=NULL){
        (*touchb).type = 0;
    }
    if (touchx < 60)
    {
        if(39<touchy&&touchy<149){
            touchb = &ch1s;
            if(touchy>105){
                (*touchb).type = 2;
            }
            else{
                (*touchb).type = 1;
            }
        }
        else if(150<touchy&&touchy<260){
            touchb = &ch2s;
            if(touchy>214){
                (*touchb).type = 2;
            }
            else{
                (*touchb).type = 1;
            }
        }
        else if(371<touchy&&touchy<371){
            touchb = &countb;
            (*touchb).type = 1;
        }
        else if(touchy>371&&touchy<479){
            touchb = &outb;
            (*touchb).type = 1;
        }
    }
    else if(touchx>723&&touchx<799){
        if(touchy<40){
            if(running){
                touchb = &stopb;
                (*touchb).type = 1;
            }
            else{
                touchb = &startb;
                (*touchb).type = 1;
            }
        }
        else if(40<touchy&&touchy<93){
            touchb = &vbt;
            (*touchb).type = 1;
        }
        else if(93<touchy&&touchy<150){
            touchb = &vbt;
            (*touchb).type = 2;
        }
        else if(150<touchy&&touchy<203){
            touchb = &vbb;
            (*touchb).type = 2;
        }
        else if(203<touchy&&touchy<371){
            touchb = &vbb;
            (*touchb).type = 1;
        }
    }
    else if(touchx>513&&touchy<40){
        if(touchx<567){
            touchb = &hbl;
            (*touchb).type = 1;
        }
        else if(567<touchx&&touchx<618){
            touchb = &hbl;
            (*touchb).type = 2;
        }
        else if(618<touchx&&touchx<671){
            touchb = &hbr;
            (*touchb).type = 2;
        }
        else if(671<touchx&&touchx<723){
            touchb = &hbr;
            (*touchb).type = 1;
        }
    }
    if(touchb!=NULL){
    if(fs){
        ((*touchb).func)();
    }
    else{
        rendbutton();
    }
    }
}